home *** CD-ROM | disk | FTP | other *** search
- //Includes
- #include <splug.h>
- #include <moni.h>
- #include <lwran.h>
- #include <lwpanel.h>
- #include <strstrea.h>
-
- //Typedefs
- typedef unsigned short int USHORT;
-
- //Defines
- #define NULL 0
-
- //Global constant (reduces string table size)
- const char * const SPACE = " ";
-
- //Function prototypes
- //
- extern "C"
- {
- int GRADActivate(long, GlobalFunc *, void *, void *);
- int GRADInterface(long, GlobalFunc *, LWInstance, void *);
- }
-
- LWInstance GRADcreate(LWError *);
- void GRADdestroy(LWInstance);
- LWError GRADcopy(LWInstance, LWInstance);
- LWError GRADload(LWInstance, const LWLoadState *);
- LWError GRADsave(LWInstance, const LWSaveState *);
- const char* GRADdescln(LWInstance);
- void GRADprocess(LWInstance, const FilterAccess *);
- unsigned int GRADflags(LWInstance);
-
-
- //Most plugins have a structure or class they store data in. This is called the instance.
- //
- class GRADIENT
- {
- public:
- //Gradient colors at the top and bottom of the image
- USHORT cTop[3], cBottom[3];
-
- private:
- };
-
-
- //The ServerRecord structure identifies all the plugins in this file to Lightwave.
- extern "C"
- {
- ServerRecord ServerDesc[] =
- {
- { "ImageFilterHandler", "LightWavin_gradient", GRADActivate },
- { "ImageFilterInterface", "LightWavin_gradient", GRADInterface },
- { NULL }
- };
- }
-
-
- //These globals allow you to use the macros to add controls in the interface.
- static LWPanControlDesc desc;
- static LWValue ival={LWT_INTEGER},ivecval={LWT_VINT},
- fval={LWT_FLOAT},fvecval={LWT_VFLOAT},sval={LWT_STRING};
-
-
- //Activation function. This function tells Lightwave where to find all the
- //functions it needs to run the plugin.
- //
- int GRADActivate(
- long version,
- GlobalFunc *global,
- void *locPtr,
- void *data
- )
- {
- ImageFilterHandler *local = reinterpret_cast<ImageFilterHandler *>(locPtr);
-
- if(version != 2) return AFUNC_BADVERSION;
-
- local->create = GRADcreate;
- local->destroy = GRADdestroy;
- local->copy = GRADcopy;
- local->load = GRADload;
- local->save = GRADsave;
- local->descln = GRADdescln;
-
- local->process = GRADprocess;
- local->flags = GRADflags;
-
- return AFUNC_OK;
- }
-
- //Creation function
- LWInstance GRADcreate(LWError *error)
- {
- GRADIENT *inst = new GRADIENT;
- return(reinterpret_cast<LWInstance>(inst));
- }
-
-
- //Destroy function
- void GRADdestroy(LWInstance inst)
- {
- if(inst)
- {
- GRADIENT *instToDelete = reinterpret_cast<GRADIENT *>(inst);
- delete instToDelete;
- return;
- }
- return;
- }
-
-
- //Copy function
- LWError GRADcopy(LWInstance from, LWInstance to)
- {
- GRADIENT *first, *second;
- first = reinterpret_cast<GRADIENT *>(from);
- second = reinterpret_cast<GRADIENT *>(to);
- *second = *first;
- return NULL;
- }
-
-
- //Save function.
- LWError GRADsave(LWInstance inst, const LWSaveState *lwss)
- {
- //Convert the instance pointer
- GRADIENT *defInst = reinterpret_cast<GRADIENT*>(inst);
-
- //Allocate the output string
- char cOutputString[32];
-
- //Enter the data
- ostrstream ostr(cOutputString, 32);
-
- ostr << defInst->cTop[0] << SPACE << defInst->cTop[1] << SPACE;
- ostr << defInst->cTop[2];
- ostr << SPACE << defInst->cBottom[0] << SPACE << defInst->cBottom[1];
- ostr << SPACE << defInst->cBottom[2] << ends;
-
- //Write the data to the scene file
- lwss->write(lwss->writeData, cOutputString, 32);
-
- return NULL;
- }
-
- //Load function
- LWError GRADload(LWInstance inst, const LWLoadState *lwls)
- {
- //Convert the instance pointer
- GRADIENT *defInst = reinterpret_cast<GRADIENT*>(inst);
-
- //Allocate the input string
- char cInputString[32];
-
- //Get the data from the scene file
- lwls->read(lwls->readData, cInputString, 32);
-
- //Extract the data into the instance
- istrstream istr(cInputString, 32);
- istr >> defInst->cTop[0] >> defInst->cTop[1] >> defInst->cTop[2];
- istr >> defInst->cBottom[0] >> defInst->cBottom[1] >> defInst->cBottom[2];
-
- return NULL;
- }
-
- //Returns a descriptive line for the plugin
- const char* GRADdescln(LWInstance inst)
- {
- return "Lightwavin' Plugin Tutorial";
- }
-
-
- //Tells LW which buffers the plugin will need
- unsigned int GRADflags(LWInstance inst)
- {
- return NULL;
- }
-
-
- //Process - The fun stuff!
- void GRADprocess(LWInstance inst, const FilterAccess *fa)
- {
- //Convert the instance
- GRADIENT *defInst = reinterpret_cast<GRADIENT*>(inst);
-
- //BufferValue pointers to process the image
- BufferValue out[3], *r, *g, *b, *a;
-
- //Create the monitor for our use
- Monitor *mon = fa->monitor;
-
- //Initialize the monitor
- MON_INIT (mon, fa->height);
-
- //Loop through the lines in the image
- for (USHORT i = 0; i < fa->height; i++) {
- r = fa->bufLine(LWBUF_RED, i);
- g = fa->bufLine(LWBUF_GREEN, i);
- b = fa->bufLine(LWBUF_BLUE, i);
- a = fa->bufLine(LWBUF_ALPHA, i);
-
- //This is the current percentage of the image that this line is
- double dPercent = i;
- dPercent /= fa->height;
-
- #pragma warning(disable : 4244)
-
- //Blend the gradient values
- unsigned char currR = (defInst->cTop[0] * (1 - dPercent)) +
- (defInst->cBottom[0] * dPercent );
- unsigned char currG = (defInst->cTop[1] * (1 - dPercent)) +
- (defInst->cBottom[1] * dPercent );
- unsigned char currB = (defInst->cTop[2] * (1 - dPercent)) +
- (defInst->cBottom[2] * dPercent );
-
- #pragma warning(default : 4244)
-
- //Divide the gradient by two (for a 50% blend with the image)
- currR /= 2;
- currG /= 2;
- currB /= 2;
-
- //Loop through the pixels in the line
- for (USHORT j = 0; j < fa->width; j++)
- {
- out[0] = (r[j] / 2) + currR;
- out[1] = (g[j] / 2) + currG;
- out[2] = (b[j] / 2) + currB;
-
- //Set the final pixels
- fa->setRGB(j, i, out);
- fa->setAlpha(j, i, a[i]);
- }
- //Step the monitor every 10th line
- if ((i % 10) == 0) MON_INCR (mon, 10);
- }
-
- //Kill the monitor
- MON_DONE (mon);
-
- return;
- }
-
-
- //The interface function
- int GRADInterface (
- long version,
- GlobalFunc *global,
- LWInstance inst,
- void *serverData
- )
- {
- //Variables used to work the
- LWPanelFuncs *panl;
- LWPanelID panID;
-
- LWControl *ctrl;
- MessageFuncs *message;
-
- GRADIENT *defInst = reinterpret_cast<GRADIENT *>(inst);
-
-
- //Get the message function ready.
- message = reinterpret_cast<MessageFuncs*>(global("Info Messages", GFUSE_TRANSIENT));
- if (!message )
- return AFUNC_BADGLOBAL;
-
- //Get the panel function ready.
- panl = reinterpret_cast<LWPanelFuncs*>(global(PANEL_SERVICES_NAME, GFUSE_TRANSIENT));
- if(!panl)
- {
- (*message->error)("Unable to activate global "PANEL_SERVICES_NAME, " please add plugin lwpanels.p" );
- return AFUNC_BADGLOBAL;
- }
-
- //This creates the panel in memory.
- panID = panl->create("Lightwavin' Plugin Tutorial Interface", NULL);
-
- //Add and set controls now.
- {
- RGB_CTL(panl, panID, "Color at top of image");
- ctrl = panl->nextControl(panID, NULL);
- SET_IVEC(ctrl, defInst->cTop[0], defInst->cTop[1], defInst->cTop[2]);
- }
- {
- RGB_CTL(panl, panID, "Color at bottom of image");
- ctrl = panl->nextControl(panID, ctrl);
- SET_IVEC(ctrl, defInst->cBottom[0], defInst->cBottom[1], defInst->cBottom[2]);
- }
-
- //This displays the panel. It returns 0 if the user clicked cancel, 1 otherwise.
- if( panl->open(panID, PANF_BLOCKING | PANF_CANCEL) )
- {
- ctrl = panl->nextControl(panID, NULL);
- GET_IVEC(ctrl, defInst->cTop[0], defInst->cTop[1], defInst->cTop[2]);
-
- ctrl = panl->nextControl(panID, ctrl);
- GET_IVEC(ctrl, defInst->cBottom[0], defInst->cBottom[1], defInst->cBottom[2]);
- }
-
- //This kills the panel.
- panl->destroy(panID);
-
- return AFUNC_OK;
- }